package cn.le.studyEnum;

import java.util.Random;

/**
 * 随机选取  方法重载
 */
public class RandomEnums {

    static Random rand = new Random(47);

    /**
     * 随机返回枚举的一个元素
     * @param ec
     * @param <T>
     * @return
     */
    public static <T extends Enum<T>> T random(Class<T> ec)
    {
        //返回枚举类的元素，如果不是枚举类型则返回null
        return random(ec.getEnumConstants());
    }
    public static <T> T random(T[] values)
    {
        return values[rand.nextInt(values.length)];
    }

    public static void main(String[] args) {

        for (int i = 0, length = 10; i < length; i++) {
            System.out.print(RandomEnums.random(Activity.class)+" ");
        }
    }
}
enum Activity
{
    STTING,LYING,STANDING,HOPPING,RUNNING,DDDGING;
}

/**
 使用节奏组织枚举
 在一个接口内部，创建实现该接口的枚举，以此将元素进行分组，可以达到将枚举元素分类组织的目的
 比如：想用enum来表示不同类别的食物，同时还希望每个enum元素依然保持Food类型
*/
interface Food{

    enum Appetizer implements  Food{
        SALAD,SOUP,SPRING_ROLLS;
    }
    enum MainCourse implements Food{
        LASAGNE,BURRITO,PAD_THAI;
    }
    enum Dessert implements Food{
        TIRAMISU,GELATO,BLACK_FOREST_CAKE;
    }
    enum Coffee implements Food{
        BLACK_COFFEE,DECAF_COFFEE,ESPESSO;
    }
}

/**
 * 创建枚举的枚举
 */
enum Course {

    APPETZER(Food.Appetizer.class),
    COFFEE(Food.Coffee.class);

    private Food[] values;

    private Course(Class<? extends Food> kind)
    {
        values = kind.getEnumConstants();
    }

    public Food randomSelection()
    {
        return RandomEnums.random(values);
    }

    /**
     * 每一个Course的实例都将其对应的class对象作为构造器的参数，通过getEnumConstants()方法，
     * 可以从该Class对象中取得某个Food子类的所有enum实例，这些实例在randomSelection()中被用到，
     * 因此，通过从每一个Course实例中随机地选择一个Food，这样就能够生成一份菜单
     */
    public static void main(String[] args) {

        for (int i = 0, length = 5; i < length; i++) {
           for (Course course: Course.values()) {
               Food food = course.randomSelection();
               System.out.print(food+" ");
           }
            System.out.println("\n-------------------");
        }
    }
}

/**
 * 将一个枚举嵌套在另一个枚举内
 */
enum SecurityCategory{

    STOCK(Security.Stock.class),
    BOND(Security.Bond.class);

    Security[] values;

    SecurityCategory(Class<? extends Security> kind)
    {
        values = kind.getEnumConstants();
    }

    /**
     * Security接口的作用是将其包含的enum组合成一个公共的类型，这一点是有必要的，然后，
     * SecurityCategory才能将Security中的enum作为其构造器的参数使用，以起到组织的效果
     */
    interface Security{
        enum Stock implements  Security
        {
            SHORT,LONG,MARGIN
        }
        enum Bond implements  Security
        {
            MUNICIPAL,JUNK
        }
    }

    public Security randomSelection()
    {
        return RandomEnums.random(values);
    }

    public static void main(String[] args) {
        for (int i = 0, length = 5; i < length; i++) {
            SecurityCategory category = RandomEnums.random(SecurityCategory.class);
            System.out.println(category +": "+category.randomSelection());
        }
        System.out.println("-----------------");
        System.out.println(SecurityCategory.values().length);
    }
}